#include "../../include/system/BankSystem.h"
#include "../../include/core/Customer.h"
#include "../../include/core/SavingsAccount.h"
#include "../../include/core/CheckingAccount.h"
#include "../../include/core/Transaction.h"
#include "../../include/system/ReportGenerator.h"
#include "../../include/system/Utils.h"

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <random>
#include <chrono>
#include <thread>
#include <limits>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include <typeinfo>

namespace MiniBanking
{

    // --- Constructor ---
    BankSystem::BankSystem()
    {
        // Seed the random number generator
        std::random_device rd;
        randomEngine_.seed(rd());
        nextTransactionIDCounter_ = 1;
    }

    // --- Main Application Loop ---
    void BankSystem::run()
    {
        int choice = 0;
        do
        {
            clearScreen();
            displayMainMenu();
            choice = promptForInt("Please choose:", 1, 5);

            switch (choice)
            {
            case 1:
                handleRegisterNewCustomer();
                break;
            case 2:
                handleAccessCustomerAccounts();
                break;
            case 3:
                handleDisplayAllAccounts();
                break;
            case 4:
                handleGenerateGlobalReport();
                break;
            case 5:
                std::cout << "\nExiting Banking System. Goodbye!\n";
                break;
            default:
                std::cout << "\nInvalid choice. Please try again.\n";
                pause();
                break;
            }
            if (choice != 5)
            {
                pause();
            }
        } while (choice != 5);
    }

    // --- UI Helper Implementations ---
    void BankSystem::displayMainMenu() const
    {
        std::cout << "===== Banking System =====\n";
        std::cout << "1. Register new customer\n";
        std::cout << "2. Access customer accounts\n";
        std::cout << "3. Display all bank accounts\n";
        std::cout << "4. Transaction reports\n";
        std::cout << "5. Exit\n";
    }

    void BankSystem::displayCustomerMenu(const Customer &customer) const
    {
        std::cout << "\n===== Customer: " << customer.getName() << " =====\n";
        std::cout << "This customer has the following accounts:\n\n";

        const BankAccount *savings = findAccountByID(customer.getSavingsAccountID());
        const BankAccount *checking = findAccountByID(customer.getCheckingAccountID());

        std::cout << std::fixed << std::setprecision(2); // Format currency
        if (savings)
        {
            std::cout << "1. Savings Account: " << savings->getAccountID() << "\n";
            std::cout << "   Balance:  ¥" << savings->getBalance() << "\n\n";
        }
        else
        {
            std::cout << "1. Savings Account: [Error retrieving account]\n\n";
        }

        if (checking)
        {
            std::cout << "2. Checking Account: " << checking->getAccountID() << "\n";
            std::cout << "   Balance:  ¥" << checking->getBalance() << "\n\n";
        }
        else
        {
            std::cout << "2. Checking Account: [Error retrieving account]\n\n";
        }

        std::cout << "Options:\n";
        std::cout << "1. Access Savings Account\n";
        std::cout << "2. Access Checking Account\n";
        std::cout << "3. View all transactions for this customer\n";
        std::cout << "4. Generate customer report\n";
        std::cout << "5. Return to main menu\n";
    }

    void BankSystem::displayAccountMenu(const BankAccount &account) const
    {
        std::cout << "\n===== Bank Account: " << account.getAccountID()
                  << " (" << account.getAccountType() << ") =====\n";
        std::cout << "Account holder: " << account.getOwnerName() << "\n";
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "Balance:  ¥" << account.getBalance() << "\n\n";

        std::cout << "Options:\n";
        // Only show Deposit/Withdraw for Checking Accounts
        const CheckingAccount *checkingAcc = dynamic_cast<const CheckingAccount *>(&account);
        int optionCounter = 1;
        if (checkingAcc)
        {
            std::cout << optionCounter++ << ". Deposit\n";
            std::cout << optionCounter++ << ". Withdraw\n";
        }
        std::cout << optionCounter++ << ". Transfer\n";
        std::cout << optionCounter++ << ". View transaction history\n";
        std::cout << optionCounter++ << ". Generate bank account report\n";
        std::cout << optionCounter++ << ". Return to customer page\n";
    }

    void BankSystem::clearScreen() const
    {
        // Platform specific - using placeholder
#ifdef _WIN32
        // system("cls"); // Can use system calls, but often discouraged
#else
        // system("clear");
#endif
        // Or just print many newlines as a portable alternative
        // std::cout << std::string(50, '\n');
        // For this example, we'll just print a separator
        std::cout << "\n----------------------------------------\n";
    }

    void BankSystem::pause() const
    {
        std::cout << "\nPress Enter to continue...";
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cin.get();
    }

    std::string BankSystem::promptForString(const std::string &prompt) const
    {
        std::string input;
        std::cout << prompt << " ";
        if (std::cin.peek() == '\n')
        {
            std::cin.ignore();
        }
        std::getline(std::cin, input);
        return input;
    }

    double BankSystem::promptForDouble(const std::string &prompt) const
    {
        double value;
        while (true)
        {
            std::cout << prompt << " ";
            std::cin >> value;
            if (std::cin.good() && value >= 0)
            {
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                return value;
            }
            else
            {
                std::cout << "Invalid input. Please enter a non-negative number.\n";
                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            }
        }
    }

    int BankSystem::promptForInt(const std::string &prompt, int minVal, int maxVal) const
    {
        int value;
        while (true)
        {
            std::cout << prompt << " ";
            std::cin >> value;
            if (std::cin.good() && value >= minVal && value <= maxVal)
            {
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                return value;
            }
            else
            {
                std::cout << "Invalid input. Please enter a number between "
                          << minVal << " and " << maxVal << ".\n";
                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            }
        }
    }

    // --- Core Logic Helper Implementations ---
    Customer *BankSystem::findCustomerByName(const std::string &name)
    {
        auto it = customers_.find(name);
        if (it != customers_.end())
        {
            return &(it->second); // Return address of the Customer object in the map
        }
        return nullptr; // Not found
    }

    // Const overload
    const Customer *BankSystem::findCustomerByName(const std::string &name) const
    {
        auto it = customers_.find(name);
        if (it != customers_.end())
        {
            return &(it->second);
        }
        return nullptr;
    }

    BankAccount *BankSystem::findAccountByID(const std::string &id)
    {
        auto it = accounts_.find(id);
        if (it != accounts_.end())
        {
            return it->second.get();
        }
        return nullptr; // Not found
    }

    // Const overload
    const BankAccount *BankSystem::findAccountByID(const std::string &id) const
    {
        auto it = accounts_.find(id);
        if (it != accounts_.end())
        {
            return it->second.get();
        }
        return nullptr;
    }

    std::string BankSystem::generateUniqueAccountID(bool isSavings)
    {
        std::uniform_int_distribution<int> dist4(1000, 9999); // For 4-digit numbers
        std::string prefix = "62";
        prefix += (isSavings ? "21" : "22"); // Account type

        std::string accountID;
        do
        {
            std::stringstream ss;
            ss << prefix << "-"
               << std::setw(4) << std::setfill('0') << dist4(randomEngine_) << "-" // Branch code
               << std::setw(4) << std::setfill('0') << dist4(randomEngine_) << "-" // Account num part 1
               << std::setw(4) << std::setfill('0') << dist4(randomEngine_);       // Account num part 2
            accountID = ss.str();
        } while (accounts_.count(accountID)); // Keep generating until unique

        return accountID;
    }

    std::string BankSystem::generateUniqueTransactionID()
    {
        std::stringstream ss;
        ss << "T" << std::setw(3) << std::setfill('0') << nextTransactionIDCounter_++;
        return ss.str();
    }

    void BankSystem::addTransaction(TransactionType type, double amount,
                                    const std::string &sourceID, const std::string &destID, const std::string &note)
    {
        std::string transID = generateUniqueTransactionID();
        auto now = std::chrono::system_clock::now();
        transactions_.emplace_back(transID, type, amount, now, sourceID, destID, note);
        // Return the ID or Transaction object if needed immediately by caller
    }

    // --- Menu Action Handler Implementations ---

    void BankSystem::handleRegisterNewCustomer()
    {
        clearScreen();
        std::cout << "===== Register New Customer =====\n";
        std::string name = promptForString("Enter customer name:");

        if (name.empty())
        {
            std::cout << "\nCustomer name cannot be empty.\n";
            return;
        }
        if (findCustomerByName(name) != nullptr)
        {
            std::cout << "\nCustomer '" << name << "' already exists.\n";
            return;
        }

        // Create customer
        Customer newCustomer(name);

        // Create accounts
        std::string savingsID = generateUniqueAccountID(true);
        std::string checkingID = generateUniqueAccountID(false);

        auto savingsAccount = std::make_unique<SavingsAccount>(savingsID, name);
        auto checkingAccount = std::make_unique<CheckingAccount>(checkingID, name);

        // Add accounts to system map BEFORE setting IDs in customer, in case of error
        accounts_[savingsID] = std::move(savingsAccount);
        accounts_[checkingID] = std::move(checkingAccount);

        // Associate accounts with customer
        newCustomer.setSavingsAccountID(savingsID);
        newCustomer.setCheckingAccountID(checkingID);

        // Add customer to system map
        customers_[name] = newCustomer; // Add the fully prepared customer

        std::cout << "\nCustomer [" << name << "] successfully registered!\n";
        std::cout << "Two bank accounts have been created:\n";
        std::cout << "- Savings Account: " << savingsID << "\n";
        std::cout << "- Checking Account: " << checkingID << "\n";
    }

    void BankSystem::handleAccessCustomerAccounts()
    {
        clearScreen();
        std::cout << "===== Access Customer Accounts =====\n";
        std::string name = promptForString("Enter customer name:");

        Customer *customer = findCustomerByName(name);
        if (!customer)
        {
            std::cout << "\nCustomer '" << name << "' not found.\n";
            return;
        }

        int customerChoice = 0;
        do
        {
            clearScreen();
            displayCustomerMenu(*customer);
            customerChoice = promptForInt("Please choose:", 1, 5);

            switch (customerChoice)
            {
            case 1: // Access Savings
                handleAccessSpecificAccount(*customer, true);
                break;
            case 2: // Access Checking
                handleAccessSpecificAccount(*customer, false);
                break;
            case 3: // View Customer Transactions
                handleViewCustomerTransactions(*customer);
                pause();
                break;
            case 4: // Generate Customer Report
                handleGenerateCustomerReport(*customer);
                pause();
                break;
            case 5:    // Return to main menu
                break; // Exit loop
            default:
                std::cout << "\nInvalid choice.\n";
                pause();
                break;
            }
        } while (customerChoice != 5);
    }

    void BankSystem::handleAccessSpecificAccount(Customer &customer, bool accessSavings)
    {
        std::string accountID = accessSavings ? customer.getSavingsAccountID() : customer.getCheckingAccountID();
        BankAccount *account = findAccountByID(accountID);

        if (!account)
        {
            std::cout << "\nError: Could not access the account.\n";
            return;
        }

        int returnOptionNumber = 0;
        int optionCounter = 1;
        bool isChecking = dynamic_cast<CheckingAccount *>(account) != nullptr;
        if (isChecking)
        {
            optionCounter += 2;
        }
        optionCounter += 3;
        returnOptionNumber = optionCounter;

        int accountChoice = 0;
        int adjustedChoice = 0;

        do
        {
            clearScreen();
            displayAccountMenu(*account);
            accountChoice = promptForInt("Please choose:", 1, returnOptionNumber);

            adjustedChoice = accountChoice;

            if (!isChecking)
            {
                if (accountChoice == 1)
                    adjustedChoice = 3; // Transfer (Savings option 1 -> Logical action 3)
                else if (accountChoice == 2)
                    adjustedChoice = 4; // History  (Savings option 2 -> Logical action 4)
                else if (accountChoice == 3)
                    adjustedChoice = 5; // Report   (Savings option 3 -> Logical action 5)
                else if (accountChoice == 4)
                    adjustedChoice = 6; // Return   (Savings option 4 -> Logical action 6)
                else
                    adjustedChoice = -1;
            }

            switch (adjustedChoice)
            {
            case 1: // Deposit (只有 Checking 会进入这里)
                handleDeposit(account);
                pause();
                break;
            case 2: // Withdraw (只有 Checking 会进入这里)
                handleWithdraw(account);
                pause();
                break;
            case 3: // Transfer (Checking 和 Savings 都会映射到这里)
                handleTransfer(account);
                pause();
                break;
            case 4: // View History (Checking 和 Savings 都会映射到这里)
                handleViewAccountHistory(*account);
                pause();
                break;
            case 5: // Generate Report (Checking 和 Savings 都会映射到这里)
                handleGenerateAccountReport(*account);
                pause();
                break;
            case 6:                                                                   // Return (Checking 和 Savings 都会映射到这里)
                break;                                                                // 退出 switch，循环条件会处理退出
            default:                                                                  // 包括 adjustedChoice == -1 的情况
                std::cout << "\nInvalid choice processed, please report this bug.\n"; // 理论不应发生
                pause();
                break;
            }

            account = findAccountByID(accountID);
            if (!account)
            {
                std::cout << "\nCritical Error: Account disappeared.\n";
                break;
            }

            // 使用 adjustedChoice == 6 作为退出条件，因为所有类型的账户的“返回”操作都被映射到了 6
        } while (adjustedChoice != 6);
    }

    void BankSystem::handleDisplayAllAccounts() const
    {
        clearScreen();
        std::cout << "===== All Bank Accounts =====\n\n";

        std::vector<const SavingsAccount *> savingsAccounts;
        std::vector<const CheckingAccount *> checkingAccounts;
        double totalBalance = 0.0;

        for (const auto &pair : accounts_)
        {
            const BankAccount *acc = pair.second.get();
            totalBalance += acc->getBalance();
            if (const SavingsAccount *sa = dynamic_cast<const SavingsAccount *>(acc))
            {
                savingsAccounts.push_back(sa);
            }
            else if (const CheckingAccount *ca = dynamic_cast<const CheckingAccount *>(acc))
            {
                checkingAccounts.push_back(ca);
            }
        }

        std::cout << "SAVINGS ACCOUNTS:\n";
        if (savingsAccounts.empty())
        {
            std::cout << "(No savings accounts)\n";
        }
        else
        {
            int count = 1;
            std::cout << std::fixed << std::setprecision(2);
            for (const auto *acc : savingsAccounts)
            {
                std::cout << count++ << ". ID: " << acc->getAccountID()
                          << "  |  Owner: " << acc->getOwnerName()
                          << "  |  Balance:  ¥" << acc->getBalance() << "\n";
            }
        }

        std::cout << "\nCHECKING ACCOUNTS:\n";
        if (checkingAccounts.empty())
        {
            std::cout << "(No checking accounts)\n";
        }
        else
        {
            int count = 1;
            std::cout << std::fixed << std::setprecision(2);
            for (const auto *acc : checkingAccounts)
            {
                std::cout << count++ << ". ID: " << acc->getAccountID()
                          << "  |  Owner: " << acc->getOwnerName()
                          << "  |  Balance:  ¥" << acc->getBalance() << "\n";
            }
        }

        std::cout << "\n--------------------\n";
        std::cout << "Total Accounts: " << accounts_.size() << "\n";
        std::cout << "Total Customers: " << customers_.size() << "\n";
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "Total Balance:  ¥" << totalBalance << "\n";
    }
    void BankSystem::handleGenerateGlobalReport() const
    {
        clearScreen();
        std::cout << "===== Transaction Reports =====\n";

        std::string generatedFilename = ReportGenerator::generateGlobalReport(transactions_);

        std::cout << "\nSystem response:\n";
        if (!generatedFilename.empty())
        {
            std::cout << "Report successfully generated as \"" << generatedFilename << "\"\n";
            std::cout << "All transactions have been saved in chronological order.\n";
        }
        else
        {
            std::cout << "Error: Failed to generate global report file.\n";
        }

        // pause();
    }

    // --- Sub-Menu Action Handlers ---

    void BankSystem::handleViewCustomerTransactions(const Customer &customer) const
    {
        clearScreen();
        std::cout << "===== Transactions for Customer: " << customer.getName() << " =====\n";
        std::string savingsID = customer.getSavingsAccountID();
        std::string checkingID = customer.getCheckingAccountID();

        std::vector<Transaction> customerTransactions;
        for (const auto &tx : transactions_)
        {
            if (tx.getSourceAccountID() == savingsID || tx.getDestinationAccountID() == savingsID ||
                tx.getSourceAccountID() == checkingID || tx.getDestinationAccountID() == checkingID)
            {
                customerTransactions.push_back(tx);
            }
        }

        std::sort(customerTransactions.begin(), customerTransactions.end());

        if (customerTransactions.empty())
        {
            std::cout << "\nNo transactions found for this customer.\n";
        }
        else
        {
            std::cout << std::fixed << std::setprecision(2);
            for (const auto &tx : customerTransactions)
            {
                auto tx_time_t = std::chrono::system_clock::to_time_t(tx.getTimestamp());
                std::cout << "ID: " << tx.getID()
                          << " | Time: " << std::put_time(std::localtime(&tx_time_t), "%Y-%m-%d %H:%M:%S")
                          << " | Type: " << transactionTypeToString(tx.getType())
                          << " | Amount:  ¥" << tx.getAmount();
                if (!tx.getSourceAccountID().empty())
                    std::cout << " | From: " << tx.getSourceAccountID();
                if (!tx.getDestinationAccountID().empty())
                    std::cout << " | To: " << tx.getDestinationAccountID();
                if (!tx.getNote().empty())
                    std::cout << " | Note: " << tx.getNote();
                std::cout << "\n";
            }
        }
    }

    void BankSystem::handleGenerateCustomerReport(const Customer &customer) const
    {
        clearScreen();
        std::cout << "===== Generate Customer Report for: " << customer.getName() << " =====\n";

        std::string generatedFilename = ReportGenerator::generateCustomerReport(customer, transactions_);

        if (!generatedFilename.empty())
        {
            std::cout << "\nSystem response:\n";
            std::cout << "Report successfully generated as \"" << generatedFilename << "\"\n";
        }
        else
        {
            std::cout << "\nSystem response:\n";
            std::cout << "Error: Failed to generate customer report file.\n";
        }

        // pause();
    }

    void BankSystem::handleDeposit(BankAccount *account)
    {
        CheckingAccount *checkingAcc = dynamic_cast<CheckingAccount *>(account);
        if (!checkingAcc)
        {
            std::cout << "\nError: Deposits are only allowed for Checking Accounts.\n";
            return;
        }

        clearScreen();
        std::cout << "===== Deposit to Account: " << checkingAcc->getAccountID() << " =====\n";
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "Current Balance:  ¥" << checkingAcc->getBalance() << "\n\n";

        double amount = promptForDouble("Enter amount to deposit:");
        std::string note = promptForString("Add note (optional):");

        if (amount <= 0)
        {
            std::cout << "\nDeposit amount must be positive.\n";
            return;
        }

        if (checkingAcc->deposit(amount))
        {
            addTransaction(TransactionType::DEPOSIT, amount, "", checkingAcc->getAccountID(), note);
            // Find the latest transaction to get its ID
            const std::string &lastTransID = transactions_.back().getID();

            std::cout << "\nDeposit successful!\n";
            std::cout << "New balance:  ¥" << checkingAcc->getBalance() << "\n";
            std::cout << "Transaction ID: " << lastTransID << " has been recorded.\n";
        }
        else
        {
            // This branch shouldn't be reached if amount > 0 for CheckingAccount::deposit
            std::cout << "\nDeposit failed. Please check the amount.\n";
        }
    }

    void BankSystem::handleWithdraw(BankAccount *account)
    {
        CheckingAccount *checkingAcc = dynamic_cast<CheckingAccount *>(account);
        if (!checkingAcc)
        {
            std::cout << "\nError: Withdrawals are only allowed for Checking Accounts.\n";
            return;
        }

        clearScreen();
        std::cout << "===== Withdraw from Account: " << checkingAcc->getAccountID() << " =====\n";
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "Current Balance:  ¥" << checkingAcc->getBalance() << "\n\n";

        double amount = promptForDouble("Enter amount to withdraw:");
        std::string note = promptForString("Add note (optional):");

        if (amount <= 0)
        {
            std::cout << "\nWithdrawal amount must be positive.\n";
            return;
        }

        if (checkingAcc->withdraw(amount))
        {
            addTransaction(TransactionType::WITHDRAW, amount, checkingAcc->getAccountID(), "", note);
            const std::string &lastTransID = transactions_.back().getID();

            std::cout << "\nWithdrawal successful!\n";
            std::cout << "New balance:  ¥" << checkingAcc->getBalance() << "\n";
            std::cout << "Transaction ID: " << lastTransID << " has been recorded.\n";
        }
        else
        {
            std::cout << "\nWithdrawal failed. Insufficient funds or invalid amount.\n";
        }
    }

    void BankSystem::handleTransfer(BankAccount *sourceAccount)
    {
        clearScreen();
        std::cout << "===== Transfer from Account: " << sourceAccount->getAccountID() << " =====\n";
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "Current Balance:  ¥" << sourceAccount->getBalance() << "\n\n";

        std::string destID = promptForString("Enter destination account ID:");
        double amount = promptForDouble("Enter amount to transfer:");
        std::string note = promptForString("Add note (optional):");

        if (amount <= 0)
        {
            std::cout << "\nTransfer amount must be positive.\n";
            return;
        }

        if (destID == sourceAccount->getAccountID())
        {
            std::cout << "\nCannot transfer to the same account.\n";
            return;
        }

        BankAccount *destAccount = findAccountByID(destID);
        if (!destAccount)
        {
            std::cout << "\nDestination account ID '" << destID << "' not found.\n";
            return;
        }

        // 1. Check Transfer Rules
        if (!sourceAccount->canTransferTo(*destAccount))
        {
            std::cout << "\nTransfer failed. This account type cannot transfer to the destination account type or owner.\n";
            return;
        }

        // 2. Check Sufficient Funds (initiateTransferOut does this)
        // 3. Perform the transfer atomically (conceptually)
        if (sourceAccount->initiateTransferOut(amount))
        { // Decreases source balance if sufficient
            // 4. Increase destination balance
            if (destAccount->receiveTransfer(amount))
            { // Use the new method
                // 5. Record transaction
                addTransaction(TransactionType::TRANSFER, amount, sourceAccount->getAccountID(), destID, note);
                const std::string &lastTransID = transactions_.back().getID();

                std::cout << "\nTransfer successful!\n";
                std::cout << "New balance:  ¥" << sourceAccount->getBalance() << "\n";
                std::cout << "Transaction ID: " << lastTransID << " has been recorded.\n";
            }
            else
            {
                // Critical failure: money deducted but not added! Need rollback.
                // For simplicity here, we just report error. In real system, transaction needs atomicity.
                std::cout << "\nCRITICAL ERROR: Transfer failed during deposit phase. Please contact support.\n";
                // Attempt to roll back (not truly transactional without more infrastructure)
                sourceAccount->receiveTransfer(amount); // Put money back (might fail if receiveTransfer has checks)
            }
        }
        else
        {
            std::cout << "\nTransfer failed. Insufficient funds.\n";
        }
    }

    void BankSystem::handleViewAccountHistory(const BankAccount &account) const
    {
        clearScreen();
        std::cout << "===== Transaction History for Account: " << account.getAccountID() << " =====\n";

        std::vector<Transaction> accountTransactions;
        for (const auto &tx : transactions_)
        {
            if (tx.getSourceAccountID() == account.getAccountID() || tx.getDestinationAccountID() == account.getAccountID())
            {
                accountTransactions.push_back(tx);
            }
        }

        std::sort(accountTransactions.begin(), accountTransactions.end());

        if (accountTransactions.empty())
        {
            std::cout << "\nNo transactions found for this account.\n";
        }
        else
        {
            std::cout << std::fixed << std::setprecision(2);
            for (const auto &tx : accountTransactions)
            {
                auto tx_time_t = std::chrono::system_clock::to_time_t(tx.getTimestamp());
                std::cout << "ID: " << tx.getID()
                          << " | Time: " << std::put_time(std::localtime(&tx_time_t), "%Y-%m-%d %H:%M:%S")
                          << " | Type: " << transactionTypeToString(tx.getType())
                          << " | Amount:  ¥" << tx.getAmount();
                if (tx.getType() == TransactionType::TRANSFER)
                {
                    if (tx.getSourceAccountID() == account.getAccountID())
                        std::cout << " | To: " << tx.getDestinationAccountID();
                    else
                        std::cout << " | From: " << tx.getSourceAccountID();
                }
                if (!tx.getNote().empty())
                    std::cout << " | Note: " << tx.getNote();
                std::cout << "\n";
            }
        }
    }

    void BankSystem::handleGenerateAccountReport(const BankAccount &account) const
    {
        clearScreen();
        std::cout << "===== Generate Account Report for: " << account.getAccountID() << " =====\n";

        std::string generatedFilename = ReportGenerator::generateAccountReport(account, transactions_); // <--- 调用 ReportGenerator

        if (!generatedFilename.empty())
        {
            std::cout << "\nSystem response:\n";
            std::cout << "Report successfully generated as \"" << generatedFilename << "\"\n"; // <--- 使用返回的文件名
        }
        else
        {
            std::cout << "\nSystem response:\n";
            std::cout << "Error: Failed to generate account report file.\n";
        }

        // pause();
    }

}
